﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace Algorithms.Common.Helpers
{
	public static class UnitTestsDataTableHelper
	{
		public static string DataTableToString(DataTable table)
		{
			var typeToStr = new Dictionary<Type, string> {{typeof(string), "s"}, {typeof(int), "i"}, {typeof(double), "d"}};
			var rv = new StringBuilder();
			Func<DataRow, string> rowToStr = r => string.Join(",", r.ItemArray.Select(v => v.ToString()));
			rv.Append(string.Join(",", table.Columns.Cast<DataColumn>().Select(c => 
				string.Format("{0}_{1}", c.ColumnName, typeToStr[c.DataType]))));
			rv.Append("|");
			rv.Append(string.Join("|", table.Rows.Cast<DataRow>().Select(rowToStr)));
			return rv.ToString();
		}

		public static DataTable DataTableFromString(string dataTxt)
		{
			var typeSelector = new Dictionary<string, Type> { { "s", typeof(string) }, { "i", typeof(int) }, { "d", typeof(double)} };
			Func<string, string> colName = s => s.Split("_".ToCharArray())[0];
			Func<string, Type> colType = s => typeSelector[s.Split("_".ToCharArray())[1]];
			var convertType = new Dictionary<Type, Func<string, object>>
			                 	{
									{typeof(string), s => s},
									{typeof(int), s => int.Parse(s)},
									{typeof(double), s => double.Parse(s)}
			                 	};

			var rv = new DataTable();
			var rows = dataTxt.Split("|".ToCharArray());
			var cols = rows.First().Split(",".ToCharArray());
			rv.Columns.AddRange(cols.Select(c => new DataColumn(colName(c), colType(c))).ToArray());
			foreach (var row in rows.Skip(1))
			{
				rv.Rows.Add(
						row.Split(",".ToCharArray())
						.Select((v, i) => convertType[rv.Columns[i].DataType](v)).ToArray()
					);
			}
			return rv;
		}
	}
}
